#include "WindowsApplication.h"

#include "WindowsPlatformMisc.h"
#include "Runtime/CGI/DynamicCGI.h"
#include "Runtime/Engine/2D/Window.h"
#include "Runtime/Logic/EngineLoop.h"
#include "Runtime/Rendering/RendererInterface.h"
#include "Runtime/Engine/GameViewportClient.h"
extern bool gIsRequestingExit;
namespace Alice{
    WindowsApplication*sWindowApplication=nullptr;
	WindowsApplication* WindowsApplication::CreateWindowsApplication(const HINSTANCE inHINSTANCE, const HICON IconHandle)
	{
		sWindowApplication=new WindowsApplication(inHINSTANCE);
		return sWindowApplication;
	}
	WindowsApplication::WindowsApplication(HINSTANCE inHInstance)
	{
		mHInstance=inHInstance;
		//WindowsApplication* windowsApplication = Alice::WindowsApplication::GetWindowsApplication();
		WNDCLASSEX wndClassEx = { 0 };
		wndClassEx.cbSize = sizeof(WNDCLASSEX);
		wndClassEx.cbClsExtra = 0;
		wndClassEx.cbWndExtra = 0;
		wndClassEx.hbrBackground = nullptr;
		wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
		wndClassEx.hIcon = nullptr;
		wndClassEx.hIconSm = nullptr;
		wndClassEx.hInstance = mHInstance;
		wndClassEx.lpfnWndProc = AppWndProc;//function
		wndClassEx.lpszMenuName = nullptr;
		wndClassEx.lpszClassName = L"BattleFire";
		wndClassEx.style = CS_HREDRAW | CS_VREDRAW;
		//create window
		ATOM atom = RegisterClassEx(&wndClassEx);
		OleInitialize(NULL);
		CoInitializeEx(NULL, 0);
		mbQuit=false;
	}
	GenericWindow* WindowsApplication::MakeWindow()
	{
		WindowsWindow*newWindow=WindowsWindow::Make();
		return newWindow;
	}
	void WindowsApplication::InitializeWindow(GenericWindow* inWindow,GenericWindow* inParentWindow, const bool bShowImmediately)
	{
		WindowsWindow* window=(WindowsWindow*)inWindow;
		WindowsWindow* parentWindow=(WindowsWindow*)inParentWindow;
		GenericWindowDefinition gwd;
		window->Initialize( this, gwd, mHInstance, parentWindow, bShowImmediately );
	}
	void WindowsApplication::PumpMessages(const float TimeDelta)
	{
		MSG msg;
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		gIsRequestingExit=mbQuit;
	}
	void WindowsApplication::ProcessDeferredEvents(const float TimeDelta)
	{
		
	}
	void WindowsApplication::Tick(const float TimeDelta)
	{
		
	}
    WindowsApplication*WindowsApplication::InitializeWindowsApplication(void* inParam){
        if (sWindowApplication != nullptr) {
            return sWindowApplication;
        }
		RECT rect = { 0 };
		rect.right = 1280;
		rect.bottom = 720;
		AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, false);
        return sWindowApplication;
    }
    WindowsApplication*WindowsApplication::GetWindowsApplication(){
		if (sWindowApplication == NULL) {
			sWindowApplication = new WindowsApplication(WindowsPlatformMisc::mInstance);
		}
        return sWindowApplication;
    }
    LRESULT CALLBACK WindowsApplication::AppWndProc(HWND inHWND, uint32 inMSG, WPARAM inWParam, LPARAM inLParam){
        return sWindowApplication->ProcessMessage(inHWND,inMSG,inWParam,inLParam);
    }
    int32 WindowsApplication::ProcessMessage(HWND inHWND, uint32 inMSG, WPARAM inWParam, LPARAM inLParam){
		switch (inMSG)
		{
		case WM_CLOSE:
			mbQuit=true;//WM_QUIT
			break;
		}
        return DefWindowProc(inHWND,inMSG,inWParam,inLParam);
    }
}
